package game.connection;

import game.Point;
import game.event.StatusEvent;
import game.snake.direction.Direction;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * All the events that occur in the game will be encapsulate in this class and
 * send through the server and client.
 * 
 * @author Sarun Wongtanakarn 5510546166
 * @author Apiwat Jierakulpanit 5510546212
 * @Version 2013.04.28
 */
public class GameEvent implements Package {

	private boolean isGrowth;
	private Map<Point, Integer> moveMap;
	private ArrayList<StatusEvent> statusList;
	private Direction direction;
	private Map<Integer, Integer> opponentData;

	public GameEvent() {
		moveMap = new HashMap<Point, Integer>();
		statusList = new ArrayList<StatusEvent>();
		opponentData = new HashMap<Integer, Integer>();
		isGrowth = false;
	}

	/** Sets growth event to this event. */
	public void growth() {
		isGrowth = true;
	}

	/**
	 * Returns ther is or there is not growth event.
	 * 
	 * @return true if there is growth event. Otherwise return false.
	 */
	public boolean isGrowth() {
		return isGrowth;
	}

	/**
	 * Returns the direction of the Snake.
	 * 
	 * @return the current direction
	 */
	public Direction getDirection() {
		return direction;
	}

	/**
	 * Sets the direction of the Snake.
	 * 
	 * @param direction
	 *            the new direction for setting
	 */
	public void setDirection(Direction direction) {
		this.direction = direction;
	}

	/** Add the opponent's data of health. */
	public void addOpponentData(int id, int health) {
		opponentData.put(id, health);
	}

	/**
	 * Returns the data of the opponents.
	 * 
	 * @return the unmodifiable map of opponent's data
	 */
	public Map<Integer, Integer> getOpponentData() {
		return Collections.unmodifiableMap(opponentData);
	}

	/**
	 * Adds move event to this event.
	 * 
	 * @param point
	 *            the point that will chamged
	 * @param value
	 *            the new value for the point
	 */
	public void addMoveEvent(Point point, int value) {
		moveMap.put(point, value);
	}

	/**
	 * Adds status event to this event.
	 * 
	 * @param event
	 *            he status event for adding
	 */
	public void addStatusEvent(StatusEvent event) {
		statusList.add(event);
	}

	/**
	 * Returns the move map of the snake in this event.
	 * 
	 * @return the unmodifiable move map
	 */
	public Map<Point, Integer> getMoveMap() {
		return Collections.unmodifiableMap(moveMap);
	}

	/**
	 * Returns the status event in this event.
	 * 
	 * @return the unmodifiable status map
	 */
	public List<StatusEvent> getStatusEvent() {
		return Collections.unmodifiableList(statusList);
	}

	@Override
	public Object unpack() {
		return this;
	}

	@Override
	public PackageType getType() {
		return PackageType.GAME_EVENT;
	}

	@Override
	public String toString() {
		String s = " { ";
		for (Point p : moveMap.keySet())
			s += "[" + p.X + "]" + "[" + p.Y + "]" + "=" + moveMap.get(p) + " ";
		return s + "}\n";
	}

}
